# 1. 引子
SurfaceFlinger 中也有一颗树,与 WMS 中的窗口容器树相对应,树的节点类型是 Layer,所以我们称之为 Layer 树。不同于 WMS, SurfaceFlinger 中没有复杂的构建 Layer 树的逻辑,那 SurfaceFilinger 中如何构建出这颗树呢?WMS 这边创建一个窗口容器树节点的同时,会创建一个 SurfaceControl 对象,这个过程中会向 SurfaceFlinger 发起远程调用,SurfaceFlinger 端会创建一个对应的 Layer 对象。
# 2. Layer 树的创建过程
两个关键点:
- Layer 创建的时机,根节点和非根节点是不同的
- Layer 之间父子关系的建立
# 2.1 Layer 树根节点的创建过程
前文我们说到,在系统启动时,会去构建窗口容器树,在这个过程中会调用到 DisplayContent 的构造函数:
// frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
DisplayContent(Display display, RootWindowContainer root,
@NonNull DeviceStateController deviceStateController) {
// .....
configureSurfaces(pendingTransaction);
// .....
}
2
3
4
5
6
7
8
DisplayContent 的构造函数中会调用到 configureSurfaces 方法:
// # DisplayContent
private final SurfaceSession mSession = new SurfaceSession();
private void configureSurfaces(Transaction transaction) {
// 构建一个SurfaceControl
final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession)
.setOpaque(true)
.setContainerLayer() // 设置为容器类型的Layer
.setCallsite("DisplayContent");
// 设置名字后构建 (Display 0 name="XXX")
mSurfaceControl = b.setName(getName()).setContainerLayer().build();
//......
}
2
3
4
5
6
7
8
9
10
11
12
13
这里会构建一个 SurfaceControl 对象,在构建 SurfaceControl 对象的过程中会向 SurfaceFlinger 发起远程调用,SurfaceFlinger 会创建一个与 DisplayContent 对应的 Layer 对象。
SurfaceControl 创建的细节不是本文的重点,这部分会在现实系统部分讲解。
此时,根节点 DisplayContent 对应的 Layer 已经构建好了。
# 2.2 Layer 树其他节点的创建过程
Layer 树其他节点的创建过程就要复杂一点了。
在 PendingArea 树转换过程中,会调用到 PendingArea root 节点的 instantiateChildren 方法.
// #PendingArea
void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,
int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {
mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));
// 遍历每一个子节点
for (int i = 0; i < mChildren.size(); i++) {
final PendingArea child = mChildren.get(i);
// PendingArea -> DisplayArea
final DisplayArea area = child.createArea(parent, areaForLayer);
if (area == null) {
// TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can
// be null.
continue;
}
// 这里的 parent 就是 DisplayContent
parent.addChild(area, WindowContainer.POSITION_TOP);
if (child.mFeature != null) {
areas.get(child.mFeature).add(area);
}
// 递归调用
child.instantiateChildren(area, areaForLayer, level + 1, areas);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
这里会把 PendingArea 转换为 DisplayArea,然后通过 addChild 建立起 DisplayArea 之间的树关系,
其中很重要的一点,addChild 中还会构建当前节点的 SurfaceControl,与之同时会远程访问到 SurfaceFlinger,SurfaceFlinger 中创建对应的 Layer 对象。
addChild 定义在父类 WindowContainer 中:
// # WindowContainer
protected final WindowList<E> mChildren = new WindowList<E>();
void addChild(E child, int index) {
if (!child.mReparenting && child.getParent() != null) {
throw new IllegalArgumentException("addChild: container=" + child.getName()
+ " is already a child of container=" + child.getParent().getName()
+ " can't add to container=" + getName()
+ "\n callers=" + Debug.getCallers(15, "\n"));
}
if ((index < 0 && index != POSITION_BOTTOM)
|| (index > mChildren.size() && index != POSITION_TOP)) {
throw new IllegalArgumentException("addChild: invalid position=" + index
+ ", children number=" + mChildren.size());
}
if (index == POSITION_TOP) {
index = mChildren.size();
} else if (index == POSITION_BOTTOM) {
index = 0;
}
// 建立树关系
mChildren.add(index, child);
// 关注点
child.setParent(this);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
setParent 方法具体代码如下:
// # WindowContainer
// 父节点,这里就是 DisplayContent
private WindowContainer<WindowContainer> mParent = null;
final protected void setParent(WindowContainer<WindowContainer> parent) {
// ......
// 关注点
onParentChanged(mParent, oldParent);
// ......
}
2
3
4
5
6
7
8
9
10
11
onParentChanged 的实现如下:
// # WindowContainer
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent,
PreAssignChildLayersCallback callback) {
super.onParentChanged(newParent, oldParent);
// mParent 是 DisplayContent
if (mParent == null) {
return;
}
if (mSurfaceControl == null) { // 当前节点的 mSurfaceControl 为 null
// If we don't yet have a surface, but we now have a parent, we should
// build a surface.
// 关注点
createSurfaceControl(false /*force*/);
} else {
//......
reparentSurfaceControl(getSyncTransaction(), mParent.mSurfaceControl);
}
//......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这里会调用 createSurfaceControl 去创建 Surface:
// # WindowContainer
// 触发Surface的创建
void createSurfaceControl(boolean force) {
setInitialSurfaceControlProperties(makeSurface());
}
2
3
4
5
当前代码是在 DisplayContent 的子节点 child 中。
makeSurface 的实现如下:
// # WindowContainer
// 当前容器的 Surface
protected SurfaceControl mSurfaceControl;
SurfaceControl.Builder makeSurface() {
// 拿到父节点 DisplayContent,调用 makeChildSurface
final WindowContainer p = getParent();
return p.makeChildSurface(this);
}
2
3
4
5
6
7
8
9
10
DisplayContent 中覆写了 makeChildSurface 方法:
// # DisplayContent
SurfaceControl.Builder makeChildSurface(WindowContainer child) {
SurfaceSession s = child != null ? child.getSession() : getSession();
final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();
if (child == null) {
return b;
}
return b.setName(child.getName())
.setParent(mSurfaceControl);
}
2
3
4
5
6
7
8
9
10
11
12
这里会创建好 child 的 SurfaceControl, SurfaceFlinger 侧会初始化好对应的 Layer。
setParent 方法调用,会配置好 Layer 的父节点。
如果非 DisplayContent 节点,就会执行到 WindowContainer 中的实现:
// # WindowContainer 中的实现
SurfaceControl.Builder makeChildSurface(WindowContainer child) {
// 拿到父亲
final WindowContainer p = getParent();
// Give the parent a chance to set properties. In hierarchy v1 we rely
// on this to set full-screen dimensions on all our Surface-less Layers.
// 调用父亲的 makeChildSurface 方法,再调用 setParent
return p.makeChildSurface(child)
.setParent(mSurfaceControl);
}
2
3
4
5
6
7
8
9
10
这里的 makeChildSurface 会一直递归调用,直到 getParent() 返回的是 DisplayContent 为止。然后调用到上面的 DisplayContent 中的 makeChildSurface 方法,构建好 SurfaceControl 和 Layer
Layer 之间的关系,通过这里的 setParent 方法调用建立。